<template>
  <div class="employees-container">
    <div class="app-container">
      <!-- 使用员工页头 -->
      <PageHeader>
        <template #left>
          <!-- 在PageHeader/index.vue下面.left写的是这个样式 -->
          <!-- 用插值表达式 -->
          <span> 总记录数是{{ total }}条 </span>
        </template>
        <!-- type="warning"：这是控制按钮的样式 -->
        <template #right>
          <el-button
            size="small"
            type="warning"
            @click="$router.push('/employees/upload-excel')"
            >excel上传</el-button
          >
          <el-button size="small" type="success" @click="handleDownload"
            >excel下载当前页</el-button
          >
          <el-button size="small" type="info" @click="handleDoenloadAll"
            >excel下载所有页</el-button
          >
          <el-button size="small" type="primary" @click="showDialog = true"
            >新增员工</el-button
          >
          <!-- v-permission="'point-add'" -->
          <!--按钮权限是否能进行编辑 v-permission="'里面的值适合后端所定义的值'" -->
        </template>
      </PageHeader>
      <!-- 卡片-主体内容 -->
      <el-card style="margin-top: 10px">
        <!-- 表格 sortable=""：这个命令是现实排序的按钮 -->
        <el-table :data="employeeList" border stripe width="100%">
          <el-table-column
            label="序号"
            type="index"
            :index="indexMethod"
            sortable=""
          />
          <el-table-column
            label="姓名"
            prop="username"
            sortable=""
            width="100"
          />
          <el-table-column label="头像" sortable="" width="120">
            <!-- 利用作用域插槽  用模块来显示不显示头像的照片v-imgerror="liuyifei"-->
            <template #default="{ row }">
              <img
                :src="row.staffPhoto"
                width="80"
                v-imgerror="liuyifei"
                @click="handleQrCode(row.staffPhoto)"
              />
            </template>
          </el-table-column>
          <el-table-column
            label="手机号"
            prop="mobile"
            sortable=""
            width="120"
          />
          <el-table-column
            label="工号"
            prop="workNumber"
            sortable=""
            width="120"
          />
          <el-table-column label="聘用形式" width="85" sortable="">
            <template #default="{ row }">
              <!-- 这是自己写的一个函数  右边传的参数形参  row表示当前员工对象-->
              {{ formatEmployment(row.formOfEmployment) }}
            </template>
          </el-table-column>
          <el-table-column
            label="部门"
            prop="departmentName"
            sortable=""
            width="100"
          />
          <el-table-column
            label="入职时间"
            prop="timeOfEntry"
            sortable=""
            width="100"
          />
          <el-table-column label="账户状态" width="100">
            <template #default="{ row }">
              {{ formatEnableState(row.enableState) }}
            </template>
          </el-table-column>
          <el-table-column label="操作" sortable="" fixed="right" width="280">
            <template #default="{ row }">
              <el-button
                type="text"
                size="small"
                @click="$router.push(`/employees/${row.id}`)"
                >查看</el-button
              >
              <el-button type="text" size="small">转正</el-button>
              <el-button type="text" size="small">调岗</el-button>
              <el-button type="text" size="small">离职</el-button>
              <el-button type="text" size="small" @click="handleOpen(row.id)"
                >角色</el-button
              >
              <el-button type="text" size="small" @click="handleDel(row.id)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页处理 这是element组件的内容不需要记住到时候查文档-->
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="query.page"
          :page-sizes="[3, 5, 8, 10]"
          :page-size="query.size"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
        />
      </el-card>
      <!-- 新增员工组件  @add-success="getEmployeeList"这是父组件接收-->
      <add-employee
        :show-dialog.sync="showDialog"
        @add-success="getEmployeeList"
      />
      <!-- .sync修饰符等同于下面代码 -->
      <!-- <add-employee
        :show-dialog="showDialog"
        @update:showDialog="showDialog = $event"
      /> -->
      <!-- 这里展示二维码图片 -->
      <el-dialog title="二维码" :visible="isShow" @close="isShow = false">
        <!-- 画布 -->
        <!-- canvas是个画布用来画二维码的 -->
        <canvas ref="qrCodeRef" />
      </el-dialog>
      <!-- 分配角色弹框 -->
      <el-dialog title="分配角色" :visible="isShow2" @close="handleClose">
        <!-- 复选框组 -->
        <el-checkbox-group v-model="checkedRoleList">
          <!-- label:
            1. 如果没有插槽，两个用途，既是展示的文本 也是提供给v-model用的
            2. 如果有插槽了，插槽的内容是给用户显示的，label是给v-model用的
          -->
          <!-- 进行循环遍历数组 -->
          <el-checkbox v-for="item in roleList" :key="item.id" :label="item.id">
            {{ item.name }}
          </el-checkbox>
        </el-checkbox-group>
        <template #footer>
          <el-button size="small" @click="handleClose">取消</el-button>
          <el-button size="small" type="paimary" @click="handleAssign"
            >确认</el-button
          >
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import {
  getEmployeeListAPI,
  delEmployeeAPI,
  getEmployeeDetailAPI,
  assignRoleAPI,
} from "@/api/employees";
// 模块化语法导入默认头像地址
import liuyifei from "@/assets/common/00.jpg";
//导出常量模块（就是constant/employees.js包括职位，工位）
import obj from "@/constant/employees.js";
//导入add-employee添加员工组件
import AddEmployee from "./componts/add-employee.vue";

//Excel文件的导入和导出
//导入/上传：把excel文件中的数据读取到内存中，读出来的就是一个数组，基于数组做列表渲染

import { export_json_to_excel } from "@/vendor/Export2Excel"; //导出excel
import QrCode from "qrcode"; //导入转化为二维码的组件
import { getRoleListAPI } from "@/api/settings"; //导入获取角色列表
export default {
  name: "EmployeesView",
  components: {
    AddEmployee,
  },
  data() {
    return {
      // 选中的角色列表给v-model用的
      checkedRoleList: [],
      // 所有的角色列表
      roleList: [],
      employeeList: [], //员工列表
      total: 0, // 数据总条数
      query: {
        //这两个参数要和后台的数据一致
        page: 1, //页码
        size: 5, //条数
      },
      //员工默认头像
      liuyifei,
      //控制新增员工弹框的显示
      showDialog: false,
      //控制二维码弹框的显示
      isShow: false,
      //控制分配配角
      isShow2: false,
    };
  },
  created() {
    //准备个created钩子函数，调这个方法
    this.getEmployeeList();
  },
  methods: {
    //分配角色
    async handleAssign() {
      //发起请求（把选中的角色同步到后台）
      await assignRoleAPI(this.employeeId, this.checkedRoleList);
      //关闭弹框
      this.handleClose();
      //给个成功的提示
      this.$message.success("分配角色成功");
    },
    //分配角色弹框打开时
    async handleOpen(employeeId) {
      //保存当前员工id
      this.employeeId = employeeId; //先保存id，给上面的使用
      this.isShow2 = true;
      // 发起获取所有角色列表的请求
      const resp1 = await getRoleListAPI({
        page: 1, //页面
        pagesize: this.total, // 获取所有条数
      });
      // 保存角色列表
      this.roleList = resp1.data.rows;
      // 获取当前员工信息(获取当前员工的基本角色信息)
      const resp2 = await getEmployeeDetailAPI(employeeId);
      // 回显(给v-model绑定的数组赋值角色id数组)
      this.checkedRoleList = resp2.data.roleIds;
    },
    // 分配角色弹框关闭时
    handleClose() {
      this.isShow2 = false;
      // 重置v-model绑定的数组(关闭的时候要制空，下次打开在赋值)
      this.checkedRoleList = [];
    },
    //展示的方法二维码
    handleQrCode(url) {
      if (!url) return; // 有图片才显示弹层
      //显示弹框
      this.isShow = true;
      //把点击的图片地址转换为二维码
      this.$nextTick(() => {
        QrCode.toCanvas(this.$refs.qrCodeRef, url);
      });
      // QrCode.toCanvas(cnavas的dom元素，带转换的信息);
    },
    //下载excel所有页的数组
    async handleDoenloadAll() {
      //把数据总条数同步到query.size中
      this.query.size = this.total;
      //重置页码为1
      this.query.page = 1;
      //获取员工列表
      await this.getEmployeeList();
      //调用下面当前页excel下载的方法（就是不用重复写下面的代码）
      this.handleDownload();
    },
    //下载excel是当前页的数组
    handleDownload() {
      //表头数组
      const header = [
        "姓名",
        "手机号",
        "入职日期",
        "聘用形式",
        "转正日期",
        "工号",
        "部门",
      ];
      //中英文键的对应关系
      const headersRelations = {
        姓名: "username",
        手机号: "mobile",
        入职日期: "timeOfEntry",
        聘用形式: "formOfEmployment",
        转正日期: "correctionTime",
        工号: "workNumber",
        部门: "departmentName",
      };
      //处理employeelist，得到二维数组
      const data = this.employeeList.map((item) => {
        //声明一个空数组
        const arr = [];
        //遍历header数组
        header.forEach((zhkey) => {
          //根据中文key得到英文key
          const enkey = headersRelations[zhkey];
          //根据得到的英文key/item对象中取属性值，push到arr空数组中
          //如果enKey是formofEployment，需要格式化处理
          if (enkey === "formOfEmployment") {
            // 根据当前对象的聘用形式数字，去obj.hireType数组查找
            const temp = obj.hireType.find((mi) => mi.id === +item[enkey]);
            // 三元表达式:如果找到了，item是个对象，则添加value属性;否则添加未知
            arr.push(temp ? temp.value : "未知");
          } else {
            arr.push(item[enkey]);
          }
        });
        //返回
        return arr;
      });
      console.log(data);
      //调用下载excel文件的方法
      export_json_to_excel({
        //表头
        header,
        //表体（二维数组就是数组套数组）
        data,
        //文件名
        filename: `${this.$store.state.user.userInfo.companyName}员工列表`,
      });
    },
    // 获取员工列表
    async getEmployeeList() {
      // 发起获取员工列表请求
      const resp = await getEmployeeListAPI(this.query);
      //解构
      const { rows, total } = resp.data;
      // console.log(rows);
      //赋值
      this.employeeList = rows;
      this.total = total;
    },
    //自定义序号的下标
    indexMethod(index) {
      // 规则: 当前页数据的序号 + 1 + (当前页码 - 1) * 每页条数
      return index + 1 + (this.query.page - 1) * this.query.size;
    },
    //格式化聘用形式
    // find()/findIndex()/filter()/reduce()/map()/forEach()/some()/every()/sort()
    // Object.keys()/0bject.values()
    // match()/Search()/replace()/split()
    formatEmployment(formOfEmployment) {
      //********************************* */
      // 方式一： if (formOfEmployment === 1) {
      //   return "正式工";
      // } else if (formOfEmployment === 2) {
      //   return "非正式";
      // }//这样写有点麻烦，要遇到多个值，会写好多，建议使用第二种
      // ****************************************
      // 方式二：根据formOfEmployment去hireType中查找 （常量模块）/constant/employees
      const item = obj.hireType.find((item) => item.id === formOfEmployment);
      //三元表达式 ：非空校验 如果找到了返回对象的value属性;否则返回未知
      return item ? item.value : "未知";
    },
    //格式化在职状态
    formatEnableState(enableState) {
      // 根据enableState去workingState中查找（常量模块）
      const item = obj.workingState.find((item) => item.id === enableState);
      //三元表达式 ：非空校验 如果找到了返回对象的value属性;否则返回未知
      return item ? item.value : "未知";
    },
    //处理每页条数改变时
    handleSizeChange(val) {
      // console.log(`每页 ${val} 条`);
      // 更新每页条数 把选择的条数同步到query.size中
      this.query.size = val; //赋值
      // 获取角色列表调用方法, 重新请求重新 请求渲染得到列表数据
      this.getEmployeeList();
    },
    //处理当前页码变化
    handleCurrentChange(val) {
      // console.log(`当前页: ${val}`);
      //把选择的页码同步到query中因为我们给query定义的变量
      this.query.page = val;
      // 获取角色列表 调用方法, 重新请求渲染得到列表数据
      this.getEmployeeList();
    },
    //删除员工
    async handleDel(employeeId) {
      try {
        //先进行询问（就是确定一下是否删除）
        await this.$confirm("确认要删除该角色吗?", "温馨提示", {
          type: "warning", //这是一个警告符号
        });
        //确定调用接口发送请求
        await delEmployeeAPI(employeeId);
        // 如果当前页面大于1，并且employeeList中只有1条数据，需要获取上一页的数据
        if (this.query.page > 1 && this.employeeList.length === 1) {
          this.query.page--; // 让页码自减
        }
        //  重新获得员工列表
        this.getEmployeeList();
        //给个成功的提示
        this.$message.success("删除成功");
      } catch (err) {
        this.$message.error(err.message || "操作失败");
        // console.log("取消");
      }
    },
  },
};
</script>

<style>
.el-pagination {
  margin-top: 20px;
}
/* 把二维码居中处理 */
.el-dialog__body {
  text-align: center;
}
</style>
